home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / a_utils / perl / perl5a1.lha / perl5alpha1 / do / open < prev    next >
Text File  |  1992-08-15  |  5KB  |  240 lines

  1. bool
  2. do_open(stab,name,len)
  3. STAB *stab;
  4. register char *name;
  5. int len;
  6. {
  7.     FILE *fp;
  8.     register STIO *stio = stab_io(stab);
  9.     char *myname = savestr(name);
  10.     int result;
  11.     int fd;
  12.     int writing = 0;
  13.     char mode[3];        /* stdio file mode ("r\0" or "r+\0") */
  14.     FILE *saveifp = Nullfp;
  15.     FILE *saveofp = Nullfp;
  16.     char savetype = ' ';
  17.  
  18.     mode[0] = mode[1] = mode[2] = '\0';
  19.     name = myname;
  20.     forkprocess = 1;        /* assume true if no fork */
  21.     while (len && isSPACE(name[len-1]))
  22.     name[--len] = '\0';
  23.     if (!stio)
  24.     stio = stab_io(stab) = stio_new();
  25.     else if (stio->ifp) {
  26.     fd = fileno(stio->ifp);
  27.     if (stio->type == '-')
  28.         result = 0;
  29.     else if (fd <= maxsysfd) {
  30.         saveifp = stio->ifp;
  31.         saveofp = stio->ofp;
  32.         savetype = stio->type;
  33.         result = 0;
  34.     }
  35.     else if (stio->type == '|')
  36.         result = mypclose(stio->ifp);
  37.     else if (stio->ifp != stio->ofp) {
  38.         if (stio->ofp) {
  39.         result = fclose(stio->ofp);
  40.         fclose(stio->ifp);    /* clear stdio, fd already closed */
  41.         }
  42.         else
  43.         result = fclose(stio->ifp);
  44.     }
  45.     else
  46.         result = fclose(stio->ifp);
  47.     if (result == EOF && fd > maxsysfd)
  48.         fprintf(stderr,"Warning: unable to close filehandle %s properly.\n",
  49.           stab_ename(stab));
  50.     stio->ofp = stio->ifp = Nullfp;
  51.     }
  52.     if (*name == '+' && len > 1 && name[len-1] != '|') {    /* scary */
  53.     mode[1] = *name++;
  54.     mode[2] = '\0';
  55.     --len;
  56.     writing = 1;
  57.     }
  58.     else  {
  59.     mode[1] = '\0';
  60.     }
  61.     stio->type = *name;
  62.     if (*name == '|') {
  63.     /*SUPPRESS 530*/
  64.     for (name++; isSPACE(*name); name++) ;
  65.     TAINT_ENV();
  66.     TAINT_PROPER("piped open");
  67.     fp = mypopen(name,"w");
  68.     writing = 1;
  69.     }
  70.     else if (*name == '>') {
  71.     TAINT_PROPER("open");
  72.     name++;
  73.     if (*name == '>') {
  74.         mode[0] = stio->type = 'a';
  75.         name++;
  76.     }
  77.     else
  78.         mode[0] = 'w';
  79.     writing = 1;
  80.     if (*name == '&') {
  81.       duplicity:
  82.         name++;
  83.         while (isSPACE(*name))
  84.         name++;
  85.         if (isDIGIT(*name))
  86.         fd = atoi(name);
  87.         else {
  88.         stab = stabent(name,FALSE);
  89.         if (!stab || !stab_io(stab)) {
  90. #ifdef EINVAL
  91.             errno = EINVAL;
  92. #endif
  93.             goto say_false;
  94.         }
  95.         if (stab_io(stab) && stab_io(stab)->ifp) {
  96.             fd = fileno(stab_io(stab)->ifp);
  97.             if (stab_io(stab)->type == 's')
  98.             stio->type = 's';
  99.         }
  100.         else
  101.             fd = -1;
  102.         }
  103.         if (!(fp = fdopen(fd = dup(fd),mode))) {
  104.         close(fd);
  105.         }
  106.     }
  107.     else {
  108.         while (isSPACE(*name))
  109.         name++;
  110.         if (strEQ(name,"-")) {
  111.         fp = stdout;
  112.         stio->type = '-';
  113.         }
  114.         else  {
  115.         fp = fopen(name,mode);
  116.         }
  117.     }
  118.     }
  119.     else {
  120.     if (*name == '<') {
  121.         mode[0] = 'r';
  122.         name++;
  123.         while (isSPACE(*name))
  124.         name++;
  125.         if (*name == '&')
  126.         goto duplicity;
  127.         if (strEQ(name,"-")) {
  128.         fp = stdin;
  129.         stio->type = '-';
  130.         }
  131.         else
  132.         fp = fopen(name,mode);
  133.     }
  134.     else if (name[len-1] == '|') {
  135.         TAINT_ENV();
  136.         TAINT_PROPER("piped open");
  137.         name[--len] = '\0';
  138.         while (len && isSPACE(name[len-1]))
  139.         name[--len] = '\0';
  140.         /*SUPPRESS 530*/
  141.         for (; isSPACE(*name); name++) ;
  142.         fp = mypopen(name,"r");
  143.         stio->type = '|';
  144.     }
  145.     else {
  146.         stio->type = '<';
  147.         /*SUPPRESS 530*/
  148.         for (; isSPACE(*name); name++) ;
  149.         if (strEQ(name,"-")) {
  150.         fp = stdin;
  151.         stio->type = '-';
  152.         }
  153.         else
  154.         fp = fopen(name,"r");
  155.     }
  156.     }
  157.     if (!fp) {
  158.     if (dowarn && stio->type == '<' && index(name, '\n'))
  159.         warn(warn_nl, "open");
  160.     Safefree(myname);
  161.     goto say_false;
  162.     }
  163.     Safefree(myname);
  164.     if (stio->type &&
  165.       stio->type != '|' && stio->type != '-') {
  166.     if (fstat(fileno(fp),&statbuf) < 0) {
  167.         (void)fclose(fp);
  168.         goto say_false;
  169.     }
  170.     if (S_ISSOCK(statbuf.st_mode))
  171.         stio->type = 's';    /* in case a socket was passed in to us */
  172. #ifdef HAS_SOCKET
  173.     else if (
  174. #ifdef S_IFMT
  175.         !(statbuf.st_mode & S_IFMT)
  176. #else
  177.         !statbuf.st_mode
  178. #endif
  179.     ) {
  180.         int buflen = sizeof tokenbuf;
  181.         if (getsockname(fileno(fp), tokenbuf, &buflen) >= 0
  182.         || errno != ENOTSOCK)
  183.         stio->type = 's'; /* some OS's return 0 on fstat()ed socket */
  184.                 /* but some return 0 for streams too, sigh */
  185.     }
  186. #endif
  187.     }
  188.     if (saveifp) {        /* must use old fp? */
  189.     fd = fileno(saveifp);
  190.     if (saveofp) {
  191.         fflush(saveofp);        /* emulate fclose() */
  192.         if (saveofp != saveifp) {    /* was a socket? */
  193.         fclose(saveofp);
  194.         if (fd > 2)
  195.             Safefree(saveofp);
  196.         }
  197.     }
  198.     if (fd != fileno(fp)) {
  199.         int pid;
  200.         STR *TARG;
  201.  
  202.         dup2(fileno(fp), fd);
  203.         TARG = afetch(fdpid,fileno(fp),TRUE);
  204.         pid = TARG->str_u.str_useful;
  205.         TARG->str_u.str_useful = 0;
  206.         TARG = afetch(fdpid,fd,TRUE);
  207.         TARG->str_u.str_useful = pid;
  208.         fclose(fp);
  209.  
  210.     }
  211.     fp = saveifp;
  212.     clearerr(fp);
  213.     }
  214. #if defined(HAS_FCNTL) && defined(F_SETFD)
  215.     fd = fileno(fp);
  216.     fcntl(fd,F_SETFD,fd > maxsysfd);
  217. #endif
  218.     stio->ifp = fp;
  219.     if (writing) {
  220.     if (stio->type == 's'
  221.       || (stio->type == '>' && S_ISCHR(statbuf.st_mode)) ) {
  222.         if (!(stio->ofp = fdopen(fileno(fp),"w"))) {
  223.         fclose(fp);
  224.         stio->ifp = Nullfp;
  225.         goto say_false;
  226.         }
  227.     }
  228.     else
  229.         stio->ofp = fp;
  230.     }
  231.     return TRUE;
  232.  
  233. say_false:
  234.     stio->ifp = saveifp;
  235.     stio->ofp = saveofp;
  236.     stio->type = savetype;
  237.     return FALSE;
  238. }
  239.  
  240.